package GUI.view.outlook;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.PixelGrabber;
import java.util.Locale;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.UIManager;
import javax.swing.plaf.FontUIResource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import twaver.Group;
import twaver.Node;
import twaver.PixelFilter;
import twaver.TDataBox;
import twaver.TWaverConst;
import twaver.TWaverUtil;

import com.jgoodies.looks.plastic.PlasticLookAndFeel;
import com.jgoodies.looks.plastic.PlasticTheme;

public class FreeUtil {

    public static final int DEFAULT_ICON_SIZE = 16;
    public static Icon BLANK_ICON = new Icon() {

        @Override
		public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
            //nothing.
        }

        @Override
		public int getIconWidth() {
            return DEFAULT_ICON_SIZE;
        }

        @Override
		public int getIconHeight() {
            return DEFAULT_ICON_SIZE;
        }
    };
    public static final int DEFAULT_BUTTON_SIZE = 20;
    public static final Insets ZERO_INSETS = new Insets(0, 0, 0, 0);
    public static final int LIST_SHRINKED_WIDTH = 37;
    public static final int OUTLOOK_SHRINKED_WIDTH = 37;
    public static final int DEFAULT_SPLIT_WIDTH = 4;
    public static final int TABLE_CELL_LEADING_SPACE = 5;
    public static final Color DEFAULT_SELECTION_COLOR = new Color(253, 192, 47);
    public static final Color BUTTON_ROVER_COLOR = new Color(196, 196, 197);
    public static final Color TABLE_HEADER_BACKGROUND_COLOR = new Color(239, 240, 241);
    public static final Color TABLE_HEADER_BORDER_BRIGHT_COLOR = Color.white;
    public static final Color TABLE_HEADER_BORDER_DARK_COLOR = new Color(215, 219, 223);
    public static final Color TABLE_ODD_ROW_COLOR = new Color(233, 231, 235);
    public static final Color TABLE_TEXT_COLOR = new Color(74, 74, 81);
    public static final Color NETWORK_BACKGROUND = new Color(226, 228, 229);
    public static final Color TAB_BOTTOM_LINE_COLOR = new Color(167, 173, 175);
    public static final Color OUTLOOK_TEXT_COLOR = new Color(120, 120, 125);
    public static final Color OUTLOOK_SPLIT_COLOR = new Color(174, 171, 162);
    public static final Color LIST_SPLIT_COLOR = new Color(105, 113, 120);
    public static final Color LIST_BACKGROUND = new Color(175, 174, 176);
    public static final Color LIST_TEXT_COLOR = new Color(49, 52, 58);
    public static final Color CONTENT_PANE_BACKGROUND = new Color(92, 153, 45);
    public static final Color MENUITEM_SELECTED_BACKGROUND = new Color(166, 188, 140);
    public static final Color MENUITEM_BACKGROUND = new Color(228, 235, 218);
    public static final Color DEFAULT_TEXT_COLOR = new Color(37, 81, 54);
    public static final Color NO_COLOR = new Color(0, 0, 0, 0);
    public static final Font TABLE_HEADER_FONT = new Font("Tahoma", Font.BOLD, 11);
    public static final Font TABLE_CELL_FONT = new Font("Tahoma", Font.PLAIN, 11);
    public static final Font FONT_14_BOLD = new Font("Calibri", Font.BOLD, 14);
    public static final Font FONT_12_BOLD = new Font("Calibri", Font.BOLD, 12);
    public static final Font FONT_14_PLAIN = new Font("Calibri", Font.PLAIN, 14);
    public static final Font FONT_12_PLAIN = new Font("Calibri", Font.PLAIN, 12);
    private static final String IMAGE_URL_PREFIX = "/free/images/";

    public static TexturePaint createTexturePaint(final String imageURL) {
        return createTexturePaint(TWaverUtil.getImage(imageURL));
    }

    public static TexturePaint createTexturePaint(final Image image) {
        final int imageWidth = image.getWidth(null);
        final int imageHeight = image.getHeight(null);
        final BufferedImage bi = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
        final Graphics2D g2d = bi.createGraphics();
        g2d.drawImage(image, 0, 0, null);
        g2d.dispose();
        return new TexturePaint(bi, new Rectangle(0, 0, imageWidth, imageHeight));
    }

    public static String getImageURL(final String imageName) {
        return IMAGE_URL_PREFIX + imageName;
    }

    public static Image getImage(final String imageName) {
        return TWaverUtil.getImage(getImageURL(imageName));
    }

    public static ImageIcon getImageIcon(final String imageName) {
        return TWaverUtil.getImageIcon(getImageURL(imageName));
    }

    public static BufferedImage createDropShadow(final BufferedImage image, final int size) {
        BufferedImage shadow = new BufferedImage(
                image.getWidth() + 4 * size,
                image.getHeight() + 4 * size,
                BufferedImage.TYPE_INT_ARGB);

        final Graphics2D g2 = shadow.createGraphics();
        g2.drawImage(image, size * 2, size * 2, null);

        g2.setComposite(AlphaComposite.SrcIn);
        g2.setColor(Color.BLACK);
        g2.fillRect(0, 0, shadow.getWidth(), shadow.getHeight());

        g2.dispose();

        shadow = getGaussianBlurFilter(size, true).filter(shadow, null);
        shadow = getGaussianBlurFilter(size, false).filter(shadow, null);

        return shadow;
    }

    public static ConvolveOp getGaussianBlurFilter(final int radius, final boolean horizontal) {
        if (radius < 1) {
            throw new IllegalArgumentException("Radius must be >= 1");
        }

        final int size = radius * 2 + 1;
        final float[] data = new float[size];

        final float sigma = radius / 3.0f;
        final float twoSigmaSquare = 2.0f * sigma * sigma;
        final float sigmaRoot = (float) Math.sqrt(twoSigmaSquare * Math.PI);
        float total = 0.0f;

        for (int i = -radius; i <= radius; i++) {
            final float distance = i * i;
            final int index = i + radius;
            data[index] = (float) Math.exp(-distance / twoSigmaSquare) / sigmaRoot;
            total += data[index];
        }

        for (int i = 0; i < data.length; i++) {
            data[i] /= total;
        }

        Kernel kernel = null;
        if (horizontal) {
            kernel = new Kernel(size, 1, data);
        } else {
            kernel = new Kernel(1, size, data);
        }
        return new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
    }

    public static Image getNodeShadowImage(final Node node) {
        final Object value = node.getUserProperty("shadow");
        if (value instanceof Image) {
            return (Image) value;
        }
        return null;
    }

    public static void setNodeShadowImage(final Node node, final Image shadowImage) {
        node.putUserProperty("shadow", shadowImage);
    }

    public static FreeMenuBar loadMenuBar(final String xml, final ActionListener action) {
        FreeMenuBar menuBar = null;
        try {
            final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            final DocumentBuilder db = dbf.newDocumentBuilder();
            final Document doc = db.parse(FreeUtil.class.getResource(xml).openStream());

            final Element root = doc.getDocumentElement();
            final NodeList rootMenus = root.getChildNodes();
            if (rootMenus != null) {
                menuBar = new FreeMenuBar();
                for (int i = 0; i < rootMenus.getLength(); i++) {
                    final org.w3c.dom.Node menu = rootMenus.item(i);
                    if (menu.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                        if (menu.getNodeName().equalsIgnoreCase("menu")) {
                            final String text = getStringAttribute(menu, "text");
                            final FreeRootMenu rootMenu = new FreeRootMenu();
                            rootMenu.setText(text);
                            menuBar.add(rootMenu);

                            processMenuItem(menu, rootMenu, action);
                        }
                        if (menu.getNodeName().equalsIgnoreCase("logo")) {
                            final String tooltip = getStringAttribute(menu, "tooltip");
                            final String imageURL = getStringAttribute(menu, "image");

                            //add company logo here
                            menuBar.add(Box.createGlue());
                            final JLabel label = new JLabel(TWaverUtil.getImageIcon(imageURL));
                            label.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
                            label.setToolTipText(tooltip);
                            menuBar.add(label);
                        }
                    }
                }
            }
        } catch (final Exception ex) {
            ex.printStackTrace();
        }
        return menuBar;
    }

    private static void processMenuItem(final org.w3c.dom.Node menu, final JMenuItem parentMenu, final ActionListener action) {
        //menu items of a menu.
        final NodeList children = menu.getChildNodes();
        if (children != null) {
            for (int j = 0; j < children.getLength(); j++) {
                final org.w3c.dom.Node itemNode = children.item(j);
                if (itemNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                    final boolean isMenuItem = itemNode.getNodeName().equalsIgnoreCase("menuitem");
                    final boolean isMenu = itemNode.getNodeName().equalsIgnoreCase("menu");
                    if (isMenuItem || isMenu) {
                        final String text = getStringAttribute(itemNode, "text");
                        final String tooltip = getStringAttribute(itemNode, "tooltip");
                        final Icon icon = getIconAttribute(itemNode, "icon");
                        final String command = getStringAttribute(itemNode, "action");

                        JMenuItem menuItem = null;

                        if (isMenu) {
                            menuItem = new FreeMenu();
                        } else {
                            menuItem = new FreeMenuItem();
                            menuItem.addActionListener(action);
                        }
                        menuItem.setText(text);
                        menuItem.setToolTipText(tooltip);
                        menuItem.setActionCommand(command);
                        menuItem.setIcon(icon);
                        parentMenu.add(menuItem);

                        if (isMenu) {
                            processMenuItem(itemNode, menuItem, action);
                        }
                    }

                }
            }
        }
    }

    private static String getStringAttribute(final org.w3c.dom.Node node, final String name) {
        final org.w3c.dom.Node attribute = node.getAttributes().getNamedItem(name);
        if (attribute != null) {
            return attribute.getNodeValue();
        } else {
            return null;
        }
    }

    private static Icon getIconAttribute(final org.w3c.dom.Node node, final String name) {
        final String iconURL = getStringAttribute(node, name);
        if (iconURL != null && !iconURL.isEmpty()) {
            return TWaverUtil.getIcon(iconURL);
        }
        return null;
    }

    private static int getIntAttribute(final org.w3c.dom.Node node, final String name) {
        final String value = getStringAttribute(node, name);
        if (value != null && !value.isEmpty()) {
            return Integer.valueOf(value);
        }
        return 0;
    }

    /*public static void loadOutlookToolBar(final String xml, final FreeOutlookHeader header, final ActionListener action) {
        try {
            final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            final DocumentBuilder db = dbf.newDocumentBuilder();
            final Document doc = db.parse(FreeUtil.class.getResource(xml).openStream());

            final Element root = doc.getDocumentElement();
            final NodeList buttons = root.getChildNodes();
            if (buttons != null) {
                for (int i = 0; i < buttons.getLength(); i++) {
                    final org.w3c.dom.Node buttonNode = buttons.item(i);
                    if (buttonNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                        if (buttonNode.getNodeName().equalsIgnoreCase("button")) {
                            final String tooltip = getStringAttribute(buttonNode, "tooltip");
                            final Icon icon = getIconAttribute(buttonNode, "icon");
                            final String command = getStringAttribute(buttonNode, "action");
                            header.addButton(icon, tooltip, action, command);
                        }
                        if (buttonNode.getNodeName().equalsIgnoreCase("separator")) {
                            header.addSeparator();
                        }
                    }
                }
            }
        } catch (final Exception ex) {
            ex.printStackTrace();
        }
    }
*/
    public static void loadOutlookPane(final String xml,
            final FreeOutlookPane outlookPane
          ) {
        try {
            final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            final DocumentBuilder db = dbf.newDocumentBuilder();
            final Document doc = db.parse(FreeUtil.class.getResource(xml).openStream());

            final Element root = doc.getDocumentElement();
            final NodeList modules = root.getChildNodes();
            if (modules != null) {
                for (int i = 0; i < modules.getLength(); i++) {
                    final org.w3c.dom.Node moduleNode = modules.item(i);
                    if (moduleNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                        if (moduleNode.getNodeName().equalsIgnoreCase("module")) {
                            final String text = getStringAttribute(moduleNode, "text");
                            final Icon icon = getIconAttribute(moduleNode, "icon");
                            final Icon iconSelected = getIconAttribute(moduleNode, "selected_icon");
                           // System.out.println(text);
                            final FreeOutlookBar bar = outlookPane.addBar(text, icon, iconSelected);
                            /*FreeUtil.loadNetwork(networkXml, bar.getNetwork(),
                                    nodeAction, nodeButtonAction, shortcutAction);*/
                            final FreeOutlookList barlist = bar.getList();
                            final Element el = (Element) moduleNode;
                           // System.out.println(el.getChildNodes().getLength());
                            for(int j=0;j<el.getChildNodes().getLength();j++){
                            	final org.w3c.dom.Node submoduleNode = el.getChildNodes().item(j);
                            	if(submoduleNode.getNodeName().equalsIgnoreCase("submodule")){
                            		  final String subtext = getStringAttribute(submoduleNode, "text");
                            		  barlist.getOutlookListModel().addElement(subtext);
                            		  
                            	}
                            }
                        }
                    }
                }
            }
        } catch (final Exception ex) {
            ex.printStackTrace();
        }
    }

   /* public static void loadNetwork(String xml, FreeNetwork network,
            ActionListener nodeAction,
            ActionListener nodeButtonAction,
            ActionListener shortcutAction) {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(FreeUtil.class.getResource(xml).openStream());

            Element root = doc.getDocumentElement();
            NodeList elements = root.getChildNodes();
            if (elements != null) {
                for (int i = 0; i < elements.getLength(); i++) {
                    org.w3c.dom.Node elementNode = elements.item(i);
                    if (elementNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                        if (elementNode.getNodeName().equalsIgnoreCase("node")) {
                            String networkName = getHtmlLabelText(getStringAttribute(elementNode, "network_text"));
                            String text = getStringAttribute(elementNode, "text");
                            int x = getIntAttribute(elementNode, "x");
                            int y = getIntAttribute(elementNode, "y");
                            String moduleIcon = getStringAttribute(elementNode, "icon");
                            String tooltip = getStringAttribute(elementNode, "tooltip");
                            String listIcon = getStringAttribute(elementNode, "list_icon");

                            FreeNode twaverNode = new FreeNode();
                            twaverNode.setLocation(x, y);
                            twaverNode.setModuleIcon(moduleIcon);
                            twaverNode.setIcon(listIcon);
                            twaverNode.setName(text);
                            twaverNode.setNetworkName(networkName);
                            twaverNode.setToolTipText(tooltip);
                            twaverNode.setAction(nodeAction);

                            //three buttons.
                            readNodeButtons(elementNode, twaverNode, nodeButtonAction);

                            //load shortcut items for this node.
                            TDataBox shortcutBox = new TDataBox();
                            readNodeShortcuts(elementNode, shortcutBox, shortcutAction);
                            twaverNode.setShortcuts(shortcutBox);

                            network.getDataBox().addElement(twaverNode);
                        }
                        if (elementNode.getNodeName().equalsIgnoreCase("arrow")) {
                            int x = getIntAttribute(elementNode, "x");
                            int y = getIntAttribute(elementNode, "y");
                            String direction = getStringAttribute(elementNode, "direction");
                            int rotation = getIntAttribute(elementNode, "rotation");

                            FreeLink arrow = new FreeLink();
                            arrow.setLocation(x, y);
                            arrow.setAngle(rotation);
                            arrow.setDirection(getArrowDirection(direction));

                            network.getDataBox().addElement(arrow);
                        }
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }*/

    private static void readNodeShortcuts(final org.w3c.dom.Node moduleNode, final TDataBox box, final ActionListener shortcutAction) {
        final NodeList children = moduleNode.getChildNodes();
        if (children != null) {
            for (int i = 0; i < children.getLength(); i++) {
                final org.w3c.dom.Node child = children.item(i);
                if (child.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                    if (child.getNodeName().equalsIgnoreCase("shortcuts")) {
                        final NodeList shortcuts = child.getChildNodes();
                        if (shortcuts != null) {
                            for (int j = 0; j < shortcuts.getLength(); j++) {
                                final org.w3c.dom.Node shortcut = shortcuts.item(j);
                                if (shortcut.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                                    if (shortcut.getNodeName().equalsIgnoreCase("shortcut")) {
                                        final String text = getStringAttribute(shortcut, "text");
                                        final String tooltip = getStringAttribute(shortcut, "tooltip");
                                        final String iconURL = getStringAttribute(shortcut, "icon");
                                        final String command = getStringAttribute(shortcut, "action");

                                        final Node node = new Node();
                                        node.setName(text);
                                        node.setToolTipText(tooltip);
                                        if (iconURL == null || iconURL.trim().isEmpty()) {
                                            node.setIcon(TWaverConst.BLANK_IMAGE);
                                        } else {
                                            node.setIcon(iconURL);
                                        }
                                        node.setUserObject(shortcutAction);
                                        node.setBusinessObject(command);
                                        box.addElement(node);
                                    }
                                    if (shortcut.getNodeName().equalsIgnoreCase("separator")) {
                                        final Group group = new Group();
                                        final String text = getStringAttribute(shortcut, "text");
                                        group.setName(text);
                                        box.addElement(group);
                                    }
                                }
                            }

                        }
                    }
                }
            }
        }
    }

    private static String getHtmlLabelText(String text) {
        if (text != null && !text.isEmpty()) {
            text = text.trim();
            while (text.contains("\\n")) {
                final int index = text.indexOf("\\n");
                final String leading = text.substring(0, index).trim();
                final String tailing = text.substring(index + 2).trim();
                text = leading + "<br>" + tailing;
            }
            text = "<html><center>" + text + "</center></html>";

            return text;
        }
        return null;
    }

    private static int getArrowDirection(final String directionInXML) {
        if (directionInXML.equalsIgnoreCase("right")) {
            return TWaverConst.ORIENTATION_EAST;
        }
        if (directionInXML.equalsIgnoreCase("left")) {
            return TWaverConst.ORIENTATION_WEST;
        }
        if (directionInXML.equalsIgnoreCase("up")) {
            return TWaverConst.ORIENTATION_NORTH;
        }
        if (directionInXML.equalsIgnoreCase("down")) {
            return TWaverConst.ORIENTATION_SOUTH;
        }
        if (directionInXML.equalsIgnoreCase("right_up")) {
            return TWaverConst.ORIENTATION_NORTH_EAST;
        }
        if (directionInXML.equalsIgnoreCase("right_down")) {
            return TWaverConst.ORIENTATION_SOUTH_EAST;
        }
        if (directionInXML.equalsIgnoreCase("left_up")) {
            return TWaverConst.ORIENTATION_NORTH_WEST;
        }
        if (directionInXML.equalsIgnoreCase("left_down")) {
            return TWaverConst.ORIENTATION_SOUTH_WEST;
        }

        throw new RuntimeException("Unknown direction: " + directionInXML);
    }

    private static void readNodeButtons(final org.w3c.dom.Node moduleNode, final FreeNode twaverNode, final ActionListener action) {
        final NodeList buttons = moduleNode.getChildNodes();
        if (buttons != null) {
            for (int i = 0; i < buttons.getLength(); i++) {
                final org.w3c.dom.Node buttonNode = buttons.item(i);
                if (buttonNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                    final boolean isButton1 = buttonNode.getNodeName().equalsIgnoreCase("button1");
                    final boolean isButton2 = buttonNode.getNodeName().equalsIgnoreCase("button2");
                    final boolean isButton3 = buttonNode.getNodeName().equalsIgnoreCase("button3");
                    if (isButton1 || isButton2 || isButton3) {
                        final String tooltip = getStringAttribute(buttonNode, "tooltip");
                        final String iconURL = getStringAttribute(buttonNode, "icon");
                        final String command = getStringAttribute(buttonNode, "action");

                        if (isButton1) {
                            twaverNode.setButtonTooltip1(tooltip);
                            twaverNode.setButtonIcon1(iconURL);
                            twaverNode.setActionCommand1(command);
                            twaverNode.setButtonAction1(action);
                        }
                        if (isButton2) {
                            twaverNode.setButtonTooltip2(tooltip);
                            twaverNode.setButtonIcon2(iconURL);
                            twaverNode.setActionCommand2(command);
                            twaverNode.setButtonAction2(action);
                        }
                        if (isButton3) {
                            twaverNode.setButtonTooltip3(tooltip);
                            twaverNode.setButtonIcon3(iconURL);
                            twaverNode.setActionCommand3(command);
                            twaverNode.setButtonAction3(action);
                        }
                    }
                }
            }
        }
    }

    public static FreePagePane getPagePane(final Component component) {
        if (component != null) {
            if (component.getParent() != null) {
                final Component parent = component.getParent();
                if (parent instanceof FreePagePane) {
                    return (FreePagePane) parent;
                } else {
                    return getPagePane(parent);
                }
            }
        }
        return null;
    }

    public static Image iconToImage(final Icon icon) {
        if (icon instanceof ImageIcon) {
            return ((ImageIcon) icon).getImage();
        } else {
            final int w = icon.getIconWidth();
            final int h = icon.getIconHeight();
            final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            final Graphics2D g = image.createGraphics();
            icon.paintIcon(null, g, 0, 0);
            g.dispose();
            return image;
        }
    }

    public static ImageIcon createDyedIcon(final ImageIcon icon, final Color color) {
        return createDyedIcon(icon, color, false);
    }

    public static ImageIcon createDyedIcon(final ImageIcon icon, final Color color, final boolean useTWaverFilter) {
        if (color == null) {
            return icon;
        } else {
            final int iconWidth = icon.getIconWidth();
            final int iconHeight = icon.getIconHeight();
            final BufferedImage bi = new BufferedImage(iconWidth, iconHeight, BufferedImage.TYPE_INT_ARGB);
            final Graphics2D g2d = bi.createGraphics();
            icon.paintIcon(null, g2d, 0, 0);
            g2d.dispose();
            final Image dyedImage = createDyedImage(bi, color, useTWaverFilter);
            return new ImageIcon(dyedImage);
        }
    }

    public static Image createDyedImage(final Image image, final Color color, final boolean useTWaverFilter) {
        if (color == null) {
            return image;
        } else {
            if (image != null) {
                final int w = image.getWidth(null);
                final int h = image.getHeight(null);

                final int[] pixels = new int[w * h];
                final PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pixels, 0, w);
                try {
                    pg.grabPixels();
                } catch (final InterruptedException ex) {
                    ex.printStackTrace();
                    return null;
                }

                final BufferedImage bi = new BufferedImage(w > 1 ? w : 1,
                        h > 1 ? h : 1,
                        BufferedImage.TYPE_INT_ARGB);
                final PixelFilter pixelFilter = TWaverUtil.getPixelFilter();
                for (int i = 0; i < pixels.length; i++) {
                    int pixel = pixels[i];
                    final int row = i / w;
                    final int col = i % w;
                    if (color != null) {
                        if (pixel != 0) {
                            if (useTWaverFilter) {
                                pixel = pixelFilter.filter(pixel, color);
                            } else {
                                pixel = color.getRGB();
                            }
                        }
                    }
                    bi.setRGB(col, row, pixel);
                }

                return bi;
            } else {
                return null;
            }
        }
    }

    public static Icon createMovedIcon(final Icon icon) {
        return createMovedIcon(icon, 1, 1);
    }

    public static Icon createMovedIcon(final Icon icon, final int offsetX, final int offsetY) {
        return new Icon() {

            @Override
			public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
                icon.paintIcon(c, g, x + offsetX, y + offsetY);
            }

            @Override
			public int getIconWidth() {
                return icon.getIconWidth();
            }

            @Override
			public int getIconHeight() {
                return icon.getIconHeight();
            }
        };
    }

    public static void setupLookAndFeel() {
        Locale.setDefault(TWaverConst.EN_US);
        TWaverUtil.setLocale(TWaverConst.EN_US);
        final PlasticTheme theme = new com.jgoodies.looks.plastic.theme.ExperienceGreen() {

            @Override
            public FontUIResource getControlTextFont() {
                return new FontUIResource(new Font("Calibri", Font.PLAIN, 11));
            }
        };
        PlasticLookAndFeel.setPlasticTheme(theme);
        try {
            UIManager.setLookAndFeel("com.jgoodies.looks.plastic.Plastic3DLookAndFeel");
        } catch (final Exception ex) {
            ex.printStackTrace();
        }
        //use my tab ui.
        //UIManager.getDefaults().put("TabbedPaneUI", FreeTabbedPaneUI.class.getName());
        UIManager.put("Menu.selectionBackground", FreeUtil.NO_COLOR);
        UIManager.put("MenuItem.selectionBackground", FreeUtil.MENUITEM_SELECTED_BACKGROUND);
        //UIManager.put("PopupMenu.border", new FreePopupMenuBorder());
        UIManager.put("ToolTip.font", FreeUtil.FONT_14_BOLD);
        UIManager.put("TabbedPane.contentBorderInsets", FreeUtil.ZERO_INSETS);
        UIManager.put("TabbedPane.tabInsets", FreeUtil.ZERO_INSETS);
        UIManager.put("TabbedPane.selectedTabPadInsets", FreeUtil.ZERO_INSETS);
        UIManager.put("TabbedPane.tabAreaInsets", FreeUtil.ZERO_INSETS);
    }
}
